cmake_minimum_required(VERSION 3.10)


#指定编译平台/架构与语言标准
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)


#指定工具链
set(CMAKE_C_COMPILER "arm-none-eabi-gcc")
set(CMAKE_CXX_COMPILER "arm-none-eabi-gcc")
set(CMAKE_AS_COMPILER "arm-none-eabi-gcc")


#跳过编译器检查
set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_FORCED TRUE)


#项目工程名
project(HC32_CMake C CXX ASM)
set(TARGET_NAME appTemplete)


set(MCU_FLAGS -mcpu=cortex-m0plus -mfloat-abi=softfp)#设置软件浮点以及芯片架构
set(OPTIMIZE_FLAGS -g -Og)#设置编译优化选项
set(LINK_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/HC32L13x.ld")#链接脚本位置


#添加编译选项函数
#-flto: 启用链接时优化 (Link-Time Optimization)
#-mthumb: 使用 Thumb 指令集进行编译
#-mabi=aapcs: 指定编译器使用 AAPCS (ARM Architecture Procedure Call Standard) ABI
#-Wall: 启用所有警告
#-Werror: 将警告视为错误，编译过程将中断
#-std=c99: 使用 C99 标准进行编译
#-ffunction-sections: 将每个函数放置在单独的节(section)中，以便进行精细的链接
#-fdata-sections: 将每个全局变量放置在单独的节(section)中
#-nostdlib: 不使用标准库
#-nostartfiles: 不使用启动文件
add_compile_options(-flto -mthumb -mabi=aapcs ${MCU_FLAGS} ${OPTIMIZE_FLAGS} 
    -Wall -Werror -std=c99 -ffunction-sections -fdata-sections -nostdlib -nostartfiles -c 
    
    # 优先调用弱符号
    -Wl,--wrap=NMI_Handler
    -Wl,--wrap=HardFault_Handler
    -Wl,--wrap=SVC_Handler
    -Wl,--wrap=PendSV_Handler
    -Wl,--wrap=SysTick_Handler

    -Wl,--wrap=PORTA_IRQHandler
    -Wl,--wrap=PORTB_IRQHandler
    -Wl,--wrap=PORTC_IRQHandler
    -Wl,--wrap=PORTD_IRQHandler
    -Wl,--wrap=DMAC_IRQHandler
    -Wl,--wrap=UART0_IRQHandler
    -Wl,--wrap=UART1_IRQHandler
    -Wl,--wrap=LPUART0_IRQHandler
    -Wl,--wrap=LPUART1_IRQHandler
    -Wl,--wrap=SPI0_IRQHandler
    -Wl,--wrap=SPI1_IRQHandler
    -Wl,--wrap=I2C0_IRQHandler
    -Wl,--wrap=I2C1_IRQHandler
    -Wl,--wrap=TIM0_IRQHandler
    -Wl,--wrap=TIM1_IRQHandler
    -Wl,--wrap=TIM2_IRQHandler
    -Wl,--wrap=LPTIM_IRQHandler
    -Wl,--wrap=TIM4_IRQHandler
    -Wl,--wrap=TIM5_IRQHandler
    -Wl,--wrap=TIM6_IRQHandler
    -Wl,--wrap=PCA_IRQHandler
    -Wl,--wrap=WDT_IRQHandler
    -Wl,--wrap=RTC_IRQHandler
    -Wl,--wrap=ADC_DAC_IRQHandler
    -Wl,--wrap=PCNT_IRQHandler
    -Wl,--wrap=VC0_IRQHandler
    -Wl,--wrap=VC1_IRQHandler
    -Wl,--wrap=LVD_IRQHandler
    -Wl,--wrap=LCD_IRQHandler
    -Wl,--wrap=FLASH_RAM_IRQHandler
    -Wl,--wrap=CLKTRIM_IRQHandler
    
)


# 添加链接选项函数
#-Wl,-gc-sections: 当链接器过程中发现没有使用到的节(section)时，将这些未使用的节从最终的可执行文件中删除
#-specs=nano.specs: 使用名为 nano.specs 的链接器规范文件。这种规范文件通常用于将 C/C++ 库函数的大小减小到最小，并使用更轻量级的实现
#-specs=nosys.specs: 使用名为 nosys.specs 的链接器规范文件。这种规范文件用于指定一个不包含系统调用的运行环境，适用于一些嵌入式系统
add_link_options(${MCU_FLAGS} -T${LINK_SCRIPT} -Wl,-gc-sections -specs=nano.specs
    -specs=nosys.specs)


# 构建静态库时启用 LTO 选项 不设置会导致库编译失败
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)


#预处理开关
add_compile_definitions(__SOFTFP__)


#添加源文件
set(incs "cmsis/" "common/" "driver/inc" "driver/system" "user/main/" 
        "user/components/beep/" 
        "user/components/clk/" 
        "user/middleware/EasyLogger/driver/" 
        "user/middleware/EasyLogger/inc/" 
        "user/middleware/EasyFlash/driver/" 
        "user/middleware/EasyFlash/inc/" 
)

file(GLOB srcs
    "user/main/*.c"
)

include_directories(${incs})

# ${CMAKE_CURRENT_SOURCE_DIR}

# 添加要引用的库的子目录
add_subdirectory(driver)
add_subdirectory(user/components/beep/)
add_subdirectory(user/components/clk/)
add_subdirectory(user/middleware/EasyLogger/)
add_subdirectory(user/middleware/EasyFlash/)

# 添加主目标
add_executable("${TARGET_NAME}.elf" ${srcs})
# 将子组件链接到主目标
target_link_libraries("${TARGET_NAME}.elf" driver)
target_link_libraries("${TARGET_NAME}.elf" beep)
target_link_libraries("${TARGET_NAME}.elf" clk)
target_link_libraries("${TARGET_NAME}.elf" EasyLogger)
target_link_libraries("${TARGET_NAME}.elf" EasyFlash)

#添加自定义命令
add_custom_command(
    TARGET "${TARGET_NAME}.elf" POST_BUILD
    COMMAND objcopy -O ihex "${TARGET_NAME}.elf" "${TARGET_NAME}.hex"
    COMMAND objcopy -I ihex -O binary "${TARGET_NAME}.hex" "${TARGET_NAME}.bin"
)
